﻿
Imports osi.root.constants
Imports osi.root.connector
Imports osi.root.formation
Imports osi.root.procedure
Imports osi.root.utils

Public Class flow_datagram_adapter
    Implements datagram

    Public ReadOnly flow_dev As flow
    Private ReadOnly packet_size As UInt32

    Public Sub New(ByVal f As flow, ByVal max_packet_size As UInt32)
        assert(Not f Is Nothing)
        assert(max_packet_size > 0)
        Me.flow_dev = f
        Me.packet_size = max_packet_size
    End Sub

    Public Function receive(ByVal result As pointer(Of Byte())) As event_comb Implements block_pump.receive
        Dim buff() As Byte = Nothing
        Dim received As pointer(Of UInt32) = Nothing
        Dim ec As event_comb = Nothing
        Return New event_comb(Function() As Boolean
                                  ReDim buff(max_packet_size() - uint32_1)
                                  received = New pointer(Of UInt32)()
                                  ec = flow_dev.receive(buff, uint32_0, array_size(buff), received)
                                  Return waitfor(ec) AndAlso
                                         goto_next()
                              End Function,
                              Function() As Boolean
                                  If ec.end_result() Then
                                      If (+received) = uint32_0 Then
                                          buff = Nothing
                                      ElseIf (+received) < array_size(buff) Then
                                          ReDim Preserve buff((+received) - 1)
                                      End If
                                      Return eva(result, buff) AndAlso
                                             goto_end()
                                  Else
                                      Return False
                                  End If
                              End Function)
    End Function

    Public Function max_packet_size() As UInt32 Implements datagram.max_packet_size
        Return packet_size
    End Function

    Public Function send(ByVal buff() As Byte,
                         ByVal offset As UInt32,
                         ByVal count As UInt32,
                         ByVal sent As pointer(Of UInt32)) As event_comb Implements flow_injector.send
        Dim ec As event_comb = Nothing
        Return New event_comb(Function() As Boolean
                                  If offset + count > array_size(buff) Then
                                      Return False
                                  ElseIf count = uint32_0 Then
                                      Return eva(sent, uint32_0) AndAlso
                                             goto_end()
                                  Else
                                      ec = flow_dev.send(buff, offset, count, sent)
                                      Return waitfor(ec) AndAlso
                                             goto_next()
                                  End If
                              End Function,
                              Function() As Boolean
                                  Return ec.end_result() AndAlso
                                         goto_end()
                              End Function)
    End Function

    Public Function sense(ByVal pending As pointer(Of Boolean),
                          ByVal timeout_ms As Int64) As event_comb Implements sensor.sense
        Return flow_dev.sense(pending, timeout_ms)
    End Function
End Class
